from flask import Blueprint,request,make_response,jsonify,redirect

from utils.comm import get_ali_object
from utils.sendmobile import send_message
from utils.captcha.captcha import captcha
from utils.myjwt import myjwt
import json, random, time, requests
from utils.myredis import r
from models.models import *
from utils.md5 import md5

user_blue = Blueprint("userblue",__name__)


@user_blue.route("/getImageCode")
# 图片验证码
def getImageCode():
    # 生成图片验证码 text文字   image图片流
    name, text, image = captcha.generate_captcha()
    print("图片验证码>>>", text)
    # 从页面获取uuid做为redis key
    uuid = request.args.get("uuid")
    # 存入redis
    r.str_setex(uuid, text, 300)
    # 以流的方式生成图片验证码
    res = make_response(image)
    res.headers["Content-Type"] = 'image/jpg'
    return res

@user_blue.route("/sms_code",methods=["POST"])
# 获取手机验证码按钮校验
def sms_code():
    data = json.loads(request.data)
    mobile = data["mobile"]
    # 图片验证码
    image = data["image"]
    uuid = data["uuid"]
    if not all([mobile,image]):
        return jsonify({"code": 400, "msg":"字段不完整,请先输入图片验证码"})
    # 从redis中取出uuid
    res = r.str_get(uuid)
    if res:
        # 判断图片验证码是否正确
        if res.decode().lower() != image.lower():
            return jsonify({"code": 400, "msg": "图片验证码错误"})
        # 删除存在redis中的uuid
        r.del_key(uuid)
    else:
        return jsonify({"code": 400, "msg": "图片验证码已过期"})
    # 一分钟只能发送一次验证码，先判断队列里是否有
    j = r.str_get(mobile)
    if j:
        return jsonify({"code": 400, "msg": "一分钟只能发送一次"})
    # 如果没有，就将当前手机号加入redis
    r.list_push("sendmobile",mobile)
    return jsonify({"code": 200, "msg": "发送成功"})

# @user_blue.route("/send")
# 获取验证码  端口集成在timed.py
# def send():
#     while True:
#         for i in range(2):
#             # 查看队列长度
#             len = r.list_len("sendmobile")
#             if len > 0:
#                 # 获取队列中的手机号
#                 data = r.list_pop("sendmobile")
#                 # 解码
#                 mobile = data.decode()
#                 # 获取四位随机数
#                 code = random.randint(10000,99999)
#                 print("手机验证码>>>",code)
#                 # 获取手机验证码
#                 res = send_message(mobile,code)
#                 print(res)
#                 # 将手机号和验证码加入redis
#                 r.str_setex(mobile, code, 60)
#         time.sleep(1)
#         return jsonify({"code": 200, "msg": "获取验证码成功"})

@user_blue.route("/login",methods=["POST"])
# 登录/注册
def login():
    data = json.loads(request.data)
    mobile = data["mobile"]
    password = data["password"]
    # 密码加密
    password = md5(password)
    sms_mobile = data["sms_mobile"]
    if not all([mobile,sms_mobile,password]):
        return jsonify({"code":400,"msg":"字段不完整"})
    s = r.str_get(mobile)
    if s:
        if json.dumps(s.decode()) != json.dumps(sms_mobile):
            return jsonify({"code": 400, "msg": "手机验证码错误"})
        r.del_key(mobile)
        user = User.query.filter_by(mobile=mobile).first()
        if user:
            if password != user.password:
                return jsonify({"code": 400, "msg": "密码错误"})
            data = {"data":{"userid": user.id, "mobile": user.mobile, "exptime": int(time.time())}}
            token = myjwt.jwt_encode(data)
            return jsonify({"code": 200, "msg": "登录成功", "token": token, "userid": user.id, "mobile": user.mobile})
        else:
            ad = User(mobile=mobile,password=password,money=0,locks=0)
            db.session.add(ad)
            db.session.commit()
            data = {"data": {"userid": ad.id, "mobile": ad.mobile, "exptime": int(time.time())}}
            token = myjwt.jwt_encode(data)
            return jsonify({"code": 200, "msg": "注册并登录成功", "token": token, "userid": ad.id, "mobile": ad.mobile})
    else:
        return jsonify({"code": 400, "msg": "手机验证码过期"})

@user_blue.route("/getroles")
# 获取全部角色
def getroles():
    data = Roles.query.all()
    lst = []
    for i in data:
        lst.append({
            "id":i.id,
            "name":i.name
        })
    return jsonify({"code": 200, "msg": "获取成功","data":lst})

@user_blue.route("/wburl")
# 三方登录,获取url
def wburl():
    client_id = "3674019597"
    redirect_uri = "http://127.0.0.1:8000/user/weiboCallback/"
    # 微博平台地址
    url = "https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code" % (
        client_id, redirect_uri)
    return jsonify({"code": 200, 'url': url})

@user_blue.route("/user/weiboCallback/")
# 微博回调
def weiboCallback():
    # 获取code
    code = request.args.get("code")
    # print("code",code)
    # 向access_token接口发送post请求
    data = {"client_id": '3674019597', "client_secret": "7ae99bc0d54ead29fc8d1b9fabd78587",
            "grant_type": "authorization_code",
            'redirect_uri': 'http://127.0.0.1:8000/user/weiboCallback/', 'code': code}
    # 获取https://api.weibo.com/oauth2/access_token信息  token   uid
    res = requests.post('https://api.weibo.com/oauth2/access_token', data=data)
    # 根据返回结果操作
    # 先json转为字点获取token和uid
    message = json.loads(res.text)
    token = message['access_token']
    uid = message['uid']
    # 查询uid在数据库中是否存在，如果存在用用户信息生成jwt token返回
    wb = db.session.execute("select user.id,user.mobile from sf_login inner join user on sf_login.userid=user.id where sf_login.uid='%s'"%(str(uid)))
    wb1 = list(wb)
    # 如果存在
    if wb1:
        # 生成返回token
        for i in wb1:
            # print("i",i)
            token = myjwt.jwt_encode(
                data={"data": {"uid": i[0], "mobile": i[1], 'exp': int(time.time())}})
            # 生成token，跳转到vue中转页，保存token到
            return redirect("http://localhost:8080/about?token=" + token + "&userid=" + str(i[0]))
    else:
        # 不存在，就跳转到绑定手机号页面
        return redirect("http://localhost:8080/wblogin?token=" + str(token) + "&uid=" + str(uid))

@user_blue.route("/sflogin",methods=["POST"])
# 三方登录绑定手机号页面
def sflogin():
    data = json.loads(request.data)
    # 判断手机号是否在用户表中存在
    user = User.query.filter_by(mobile=data["mobile"]).first()
    if user:
        # 加入三方登录表
        sf = Sf_login(userid=user.id,webfrom="weibo",uid=data["uid"],token=data["token"])
        db.session.add(sf)
        db.session.commit()
        # 生成token
        data = {"data":{"userid":user.id,"mobile":user.mobile,"exptime":int(time.time())}}
        token = myjwt.jwt_encode(data)
        return jsonify({"code": 200, "msg": "登录成功", "token": token, "userid": user.id, "mobile": user.mobile})
    else:
        try:
            password = md5(data["password"])
            # 加入用户表
            admin = User(mobile=data["mobile"],roleid=1,password=password)
            db.session.add(admin)
            db.session.commit()
            # 加入三方登录表
            sf = Sf_login(userid=admin.id,webfrom="weibo",uid=data["uid"],token=data["token"])
            db.session.add(sf)
            db.session.commit()
            # 生成token
            data = {"data": {"userid": admin.id, "mobile": admin.mobile, "exptime": int(time.time())}}
            token = myjwt.jwt_encode(data)
            return jsonify({"code": 200, "msg": "登录成功", "token": token, "userid": admin.id, "mobile": admin.mobile})
        except Exception as a:
            print(a)
            return jsonify({"code":400,"msg":"错误"})

@user_blue.route("/getuser")
# 获取用户信息
def getuser():
    userid = request.args.get("userid")
    user = User.query.filter_by(id=userid).first()
    list = []
    list.append({
        "id":user.id,
        "mobile": user.mobile,
        "money":user.money,
        "create_time":str(user.create_time)
    })
    return jsonify({"code":200,"msg":"获取成功","data":list})

@user_blue.route("/setorder",methods=["POST"])
# 支付
def setorder():
    data = json.loads(request.data)
    userid = data["userid"]
    money = data["money"]
    # 订单号
    number = str(int(time.time()))+str(userid) + str(random.randint(10000, 99999))
    orders = Order(userid=userid,price=money,number=number,status=0)
    db.session.add(orders)
    db.session.commit()
    # 对生成半小时没支付的订单处理解决 ***定时任务在timed.py 页面
    # 记录过期时间
    times = int(time.time()) + 1800
    # 加入队列
    r.sortedset_add("Oredrs", number, times)
    alipay = get_ali_object()
    query_params = alipay.direct_pay(
        subject=str(userid) + ",订单",  # 商品简单描述
        # 用户购买的商品订单号（每次不一样） 20180301073422891
        out_trade_no=str(number),
        total_amount=money,  # 交易金额(单位: 元 保留俩位小数)
    )
    # 支付宝网关地址（沙箱应用）
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(
        query_params)
    return jsonify({"code": 200, "url": pay_url})

@user_blue.route("/callback")
# 支付回调
def callback():
    # 获取支付返回的参数
    data = request.args
    # 对参数进行处理
    datas = {k: v for k, v in data.items()}
    # 从字典中将sign删除
    sign = datas.pop("sign")
    # 获取支付宝对象
    alipay = get_ali_object()
    # 调用验签
    flag = alipay.verify(datas, sign)
    # print(flag)
    # 订单号
    number = datas.pop("out_trade_no")
    # 流水号
    serial_number = datas.pop("trade_no")
    if flag == True:
        r.sortedset_delete("Oredrs", number)
        try:
            # 跟新充值表订单状态
            res = Order.query.filter_by(number=number).first()
            if res:
                res.status = 1,
                res.serial_number = serial_number
                db.session.add(res)
                # db.session.commit()
            # 更新用户账号金额
            res1 = User.query.filter_by(id=res.userid).first()
            if res1:
                res1.money=int(res1.money)+int(res.price)
                db.session.add(res)
                # db.session.commit()
            # 写入账户变化表
            res3 = Change(userid=res.userid, money=res.price,status=1)
            db.session.add(res3)
            db.session.commit()
            return redirect("http://localhost:8080/user")
        except Exception as a:
            print(a)
            return jsonify({"code": 400, "msg": "错误"})





























